package utils

import (
	"errors"
	"github.com/golang-jwt/jwt/v4"
	"new_club_recruitment/global"
	"new_club_recruitment/model/admin"
	"new_club_recruitment/model/common/request"
	"time"
)

var (
	TokenExpired     = errors.New("令牌已过期")
	TokenNotValidYet = errors.New("令牌尚未激活")
	TokenMalformed   = errors.New("不是令牌")
	TokenInvalid     = errors.New("无法处理此令牌")
)

// GenToken 生成JWT
func GenToken(admin *admin.SysAdmin) (string, error) {
	// 创建一个我们自己的声明
	c := request.MyClaims{
		BaseClaims: request.BaseClaims{
			UserId:     admin.ID,
			CreateAt:   time.Now(),
			Permission: admin.Permission,
		}, //权限
		RegisteredClaims: jwt.RegisteredClaims{
			ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Second * global.GVA_CONFIG.JWT.ExpiresTime)), // 过期时间
			Issuer:    global.GVA_CONFIG.JWT.Issuer,                                                        // 签发人
		},
	}
	// 使用指定的签名方法创建签名对象
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, c)
	// 使用指定的secret签名并获得完整的编码后的字符串token
	return token.SignedString([]byte(global.GVA_CONFIG.JWT.SigningKey))
}

// ParseToken 解析JWT
func ParseToken(tokenString string) (*request.MyClaims, error) {
	// 解析token
	token, err := jwt.ParseWithClaims(tokenString, &request.MyClaims{}, func(token *jwt.Token) (i interface{}, err error) {
		return []byte(global.GVA_CONFIG.JWT.SigningKey), nil
	})
	if err != nil {
		if ve, ok := err.(*jwt.ValidationError); ok {
			if ve.Errors&jwt.ValidationErrorMalformed != 0 {
				return nil, TokenMalformed
			} else if ve.Errors&jwt.ValidationErrorExpired != 0 {
				// Token is expired
				return nil, TokenExpired
			} else if ve.Errors&jwt.ValidationErrorNotValidYet != 0 {
				return nil, TokenNotValidYet
			} else {
				return nil, TokenInvalid
			}
		}
	}
	// 校验token
	if claims, ok := token.Claims.(*request.MyClaims); ok && token.Valid {
		return claims, nil
	}
	return nil, TokenInvalid
}
